#pragma once
#include<jsoncpp/json/json.h>
#include<iostream>
#include<string>
#include <boost/algorithm/string/case_conv.hpp>
#include"index.hpp"


class Search{
public:
Search(){};
~Search(){};

public:
    void InitSearch(std::string file_path)
    {
        ns_index::Index::Get_Index()->bulid_index(file_path);
    }

    //找到query位置再取前50和后100；
    std::string Get_summart(std::string content,std::string word)
    {
      //摘要
      std::string summart;
      //1. 找到首次出现
      auto iter = std::search(content.begin(), content.end(), word.begin(), word.end(), [](int x, int y){
              return (std::tolower(x) == std::tolower(y));
              });
      if(iter == content.end()){
        assert(false);
      }
      int pos = std::distance(content.begin(), iter);
      //不能用find直接进行查找,find区分大小写
      //int pos=content.find(query);
      // if(pos==std::string::npos)
      // {
      //   return "None1";
      // }
      
      //不够则有多少取多少
      int start=0;
      int end=content.size()-1;

      if(pos-50>start)
      {
        start=pos-50;
      }
      if(pos+100<end)
      {
        end=pos+100;
      }

      if(start>end)
      {
        assert(false);
      }
      summart=content.substr(start,end-start);

      return summart;
    }

    //获取到用户输入的关键字
    std::string get_param_value(std::string query)
    {
        //利用jieba分词对用户输入的关键字进行分词
        std::vector<std::string> words;
        Util::StringUtil::Cutstring(query,&words);
        //std::vector<ns_index::Inverted_zip> v_zip;倒排拉链本身就是一个数组
        std::vector<ns_index::InvertedDate> v_zip;
        //获取倒排拉链
        for(auto& word:words)
        {
          boost:: to_lower(word);
          //我们统一处理成小写，在搜索引擎中小写也能搜到大写
          std::vector<ns_index::InvertedDate>* zip=ns_index::Index::Get_Index()->Get_Inverted_zip(word);
          if(zip==nullptr)
          {
            continue;
          }
          //可能获取到相同的文档
          v_zip.insert(v_zip.end(),zip->begin(),zip->end());
        }

        //对获取到的内容进行排序
        std::sort(v_zip.begin(), v_zip.end(), [](const ns_index::InvertedDate& v1, const ns_index::InvertedDate& v2) {  
          return v1.weight > v2.weight; // 使用正确的属性名，并返回比较结果  
        });

        //获取文档内容，并保存到json当中
        Json::Value root;
        for(auto& zip:v_zip)
        {
          Json::Value k;
          //通过文档ID获取到文档内容
          ns_index::DocInfo*info=ns_index::Index::Get_Index()->Get_DocInfo(zip.InfoId);
          if(info==nullptr)
          {
            continue;
          }

          k["title"]=info->title;
          //获取摘要，而不是获取正文
          //k["content"]=info->content;
          //注意因为我们之前全部转换成小写，所以这里可能会出现bug，Char转化成char，然后使用char在原文中查找，导致无法找到
          k["summary"]=Get_summart(info->content,zip.word);
          k["weight"]=zip.weight;
          k["infoid"]=info->InfoId;
          k["url"]=info->url;
          root.append(k);
        }

        //将json转化为字符串
        Json::StyledWriter swriter;
        std::string s=swriter.write(root);
        return s;
    }

};
